#include "rep.hpp"
#include "gc.h"

namespace rep{


  size_t ConsHelper::memSize(Slot* in){return sizeof(Cons);}
  
  Type* ConsHelper::type(Slot* in){
    //unimplemented
    return NULL;
  }

  string* ConsHelper::toString(Slot* in){
    //unimplemented
    return NULL;
  }

  int ConsHelper::hashCode(Slot* in){
    static hash<int> h; 
    return h((int) in->cell->car.i)*7 + h( (int) in->cell->cdr.i);
  }

  void ConsHelper::assign(Slot* to, Cons* rvalue){
    if(rvalue == NULL){
      to->tag = Slot::VOID;
      to->cell = NULL;
    }else{
      to->tag = Slot::CONS;
      to->cell = rvalue;
    }
  }
  
  Cons* Cons::pop(Slot* fill){
    assert(cdr.tag == Slot::CONS || cdr.tag == Slot::VOID);
    *fill = car;
    if(cdr.tag == Slot::CONS){
      return cdr.cell;
    }else{
      return NULL;
    }
  }

  Cons* Cons::push(const Slot& in){
    Cons* out = new (GC) Cons();
    out->car = in;
    if(this){
      ConsHelper::assign(&out->cdr, this);
    }else{
      Slot v;
      v.tag = Slot::VOID;
      v.cell = NULL;
      out->cdr = v;
    }
    return out;
  }

};
